/*
 * socket_address.cpp
 *
 *  Created on: 2008-7-18
 *      Author: fanliangliang
 */

#include "socket_address.h"
#include <sstream>
#include <cstring>

BEGIN_NAMESPACE_TOXIC

using namespace std;

SocketAddress::SocketAddress(const IpAddress& address /*= IpAddress::ANY*/, uint16_t port /*= 0*/)
:_address(address)
,_port(port)
,_internalAddress(0) {

}

SocketAddress::SocketAddress(const sockaddr_in& address)
:_address(address.sin_addr.s_addr)
,_port(ntohs(address.sin_port))
,_internalAddress(0) {

}

SocketAddress::~SocketAddress() {
	delete _internalAddress;
}

SocketAddress::SocketAddress(const SocketAddress& other)
:_address(other._address)
,_port(other._port)
,_internalAddress(0) {

}

SocketAddress& SocketAddress::operator=(const SocketAddress& other) {
	if (this != &other) {
		_address = other._address;
		_port = other._port;
	}
	return *this;
}

void SocketAddress::setAddress(const IpAddress& address) {
	_address = address;
}

void SocketAddress::setPort(uint16_t port) {
	_port = port;
}

const IpAddress& SocketAddress::address() const {
	return _address;
}

uint16_t SocketAddress::port() const {
	return _port;
}

bool SocketAddress::isValid() const {
	return _address.isValid();
}

string SocketAddress::toString() const {
	ostringstream oss;
	oss << _address << ':' << _port;
	return oss.str();
}

SocketAddress::operator const sockaddr*() const {
	return reinterpret_cast<const sockaddr*>(internalAddress());
}

size_t SocketAddress::size() {
	return sizeof(sockaddr_in);
}

sockaddr_in* SocketAddress::internalAddress() const {
	if (_internalAddress == 0) {
		_internalAddress = new sockaddr_in();
		memset(_internalAddress, 0, sizeof(sockaddr_in));
		_internalAddress->sin_family = AF_INET;
	}
	_internalAddress->sin_addr.s_addr = _address.value();
	_internalAddress->sin_port = htons(_port);
	return _internalAddress;
}


bool operator==(const SocketAddress& lhs, const SocketAddress& rhs) {
	return (lhs.port() == rhs.port() && lhs.address() == rhs.address());
}

bool operator!=(const SocketAddress& lhs, const SocketAddress& rhs) {
	return !(lhs == rhs);
}

ostream& operator<<(ostream& out, const SocketAddress& address) {
	return out << address.toString();
}

END_NAMESPACE_TOXIC
